using System;

namespace Waymex.Gis.Shape
{
	/// <summary>
	/// Summary description for GISPolyLine.
	/// </summary>
#if(PUBLIC)
	public class PolyLine : Waymex.Gis.Shape.ShapeBase
#else
	internal class PolyLine : Waymex.Gis.Shape.ShapeBase
#endif
	{
		private double	m_dblMinX = 0;
		private double	m_dblMinY = 0;
		private double	m_dblMaxX = 0;
		private double	m_dblMaxY = 0;
		private Parts	m_colParts = new Parts();
		private Points	m_colPoints = new Points();
		private int		m_intPointByteSize = 0;

		private int		m_intParts = 0;
		private int		m_intPoints = 0;

		public PolyLine()
		{
			m_enuType = ShapeBase.ShapeType.ShapeTypePolyLine;
		}

		internal override byte[] ToByte()
		{
			byte[] bytData = null;
			int intPartArrayIndex = 0;
			byte[] bytParts	= null;
			byte[] bytPoints	= null;

			//type
			bytData = ByteConcat(bytData,ConvertToByte((int)m_enuType, ByteOrder.ByteOrderLittleEndian));
			
			//box
			bytData = ByteConcat(bytData,ConvertToByte(m_dblMinX, ByteOrder.ByteOrderLittleEndian));
			bytData = ByteConcat(bytData,ConvertToByte(m_dblMinY, ByteOrder.ByteOrderLittleEndian));
			bytData = ByteConcat(bytData,ConvertToByte(m_dblMaxX, ByteOrder.ByteOrderLittleEndian));
			bytData = ByteConcat(bytData,ConvertToByte(m_dblMaxY, ByteOrder.ByteOrderLittleEndian));
			bytData = ByteConcat(bytData,ConvertToByte(m_intParts, ByteOrder.ByteOrderLittleEndian));
			bytData = ByteConcat(bytData,ConvertToByte(m_intPoints, ByteOrder.ByteOrderLittleEndian));
			

			foreach(Points objPoints in m_colParts)
			{
				//assuming there are points in this part, update the
				//parts array
				if(objPoints.Count > 0)
				{
					bytParts = ByteConcat(bytParts,ConvertToByte(intPartArrayIndex,ByteOrder.ByteOrderLittleEndian));
				}
				foreach(Point objPoint in objPoints)
				{
					//when adding points to the line we exclude the Point.Type data 
					bytPoints = ByteConcat(bytPoints,objPoint.GetPointBinary());
					intPartArrayIndex++;
				}
			}

			//now we can add the parts and points arrays to the final data
			bytData = ByteConcat(bytData,bytParts);
			bytData = ByteConcat(bytData,bytPoints);

			return bytData;

		}

		public bool AddPoint(Waymex.Gis.Shape.Point Point, bool NewPart)
		{

			int intLatestPart = 0;

			//increase the count of points
			m_intPoints++; 
			
			//set the size of a point if we dont already have it
			if (m_intPointByteSize == 0)
				m_intPointByteSize = Point.GetPointBinary().Length;

			// update min and max values
			//if this is the first point then handle differently
			if(m_intPoints == 1)
			{
				m_dblMaxX = Point.ValueX;
				m_dblMaxY = Point.ValueY;
				m_dblMinX = Point.ValueX;
				m_dblMinY = Point.ValueY;
			}
			else
			{
				if (m_dblMaxX < Point.ValueX)
					m_dblMaxX = Point.ValueX;
			
				if (m_dblMaxY < Point.ValueY)
					m_dblMaxY = Point.ValueY;

				if (m_dblMinX > Point.ValueX)
					m_dblMinX = Point.ValueX;
			
				if (m_dblMinY > Point.ValueY)
					m_dblMinY = Point.ValueY;			
			}

			//not appending so create a new part
			if (NewPart || m_colParts.Count == 0)
			{
				//increase the count of parts
				m_intParts++;

				//create a new points collection and add it to the parts collection
				m_colParts.Add(new Points());

			}

			intLatestPart = m_colParts.Count -1;
			m_colParts[intLatestPart].Add(Point);

			return true;
		}

		public double MinValueX
		{
			get
			{
				return m_dblMinX;
			}
		}
		public double MinValueY
		{
			get
			{
				return m_dblMinY;
			}
		}
		public double MaxValueX
		{
			get
			{
				return m_dblMaxX;
			}
		}
		public double MaxValueY
		{
			get
			{
				return m_dblMaxY;
			}
		}
		public Parts Parts
		{
			get
			{
				return m_colParts;
			}
		}
	}
}
